1 Importation de librairies, datasets
1.1 Importation librairies, liens des datasets
1.2 Importation du dataset TMDB
1.3 Importations des datasets IMDB
1.4 Fusion des dataframes
2 Exploration des dataframes
2.1 Clean-up partie 1
2.2 Filtrage
2.2.1 Durée
2.2.2 Année
2.2.3 Genre
2.2.4 Note
2.2.5 Nombre de votants
2.3 Clean-up partie 2
3 Sauvegarde du CSV
import gzip
import pandas as pd
import numpy as np
from datetime import datetime
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.express as px
import random
import plotly.graph_objs as go
import plotly.io as pio
pio.renderers.default = "plotly_mimetype+notebook"
# Liens des datasets IMDB
link_name_basics = "https://datasets.imdbws.com/name.basics.tsv.gz"
link_title_akas = "https://datasets.imdbws.com/title.akas.tsv.gz"
link_title_basics = "https://datasets.imdbws.com/title.basics.tsv.gz"
link_title_crew = "https://datasets.imdbws.com/title.crew.tsv.gz"
link_title_episode = "https://datasets.imdbws.com/title.episode.tsv.gz"
link_title_principals = "https://datasets.imdbws.com/title.principals.tsv.gz"
link_title_ratings = "https://datasets.imdbws.com/title.ratings.tsv.gz"
# Liens du dataset TMDB
link_tmdb = r"C:\Users\Félix\Downloads\tmdb_full.csv"
# r"C:\Users\Ju_u\Downloads\tmdb_full.csv"
# r"C:\Users\wilders\Downloads\tmdb_full.csv"
# Ignore les Alertes
pd.options.mode.chained_assignment = None # default='warn'
# Import warnings simplefilter
from warnings import simplefilter
simplefilter(action='ignore', category=FutureWarning)
df_tmdb = pd.read_csv(link_tmdb, low_memory=False, usecols=["id","imdb_id","genres","revenue","poster_path"])
df_tmdb.head()
| genres | id | imdb_id | poster_path | revenue | |
|---|---|---|---|---|---|
| 0 | ['Comedy'] | 3924 | tt0029927 | /zBiHKhXklvTFwj4M1uEUcQGAVJ.jpg | 0 |
| 1 | ['Adventure'] | 6124 | tt0011436 | /6xUbUCvndklbGVYiljHr34NTxSl.jpg | 0 |
| 2 | ['Drama', 'Romance'] | 8773 | tt0055747 | /aup2QCYCsyEeQfpboXy0f4uj8aE.jpg | 0 |
| 3 | ['Drama', 'Comedy', 'Crime'] | 2 | tt0094675 | /ojDg0PGvs6R9xYFodRct2kdI6wC.jpg | 0 |
| 4 | ['Drama', 'Comedy', 'Romance'] | 3 | tt0092149 | /nj01hspawPof0mJmlgfjuLyJuRN.jpg | 0 |
df_tmdb.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 309572 entries, 0 to 309571 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 genres 309572 non-null object 1 id 309572 non-null int64 2 imdb_id 309572 non-null object 3 poster_path 264159 non-null object 4 revenue 309572 non-null int64 dtypes: int64(2), object(3) memory usage: 11.8+ MB
# Vérification des duplicates sur l'ID
df_tmdb.duplicated(subset=['id']).sum()
0
data_title_basics = pd.read_csv(link_title_basics, compression='gzip', header=0, sep='\t', low_memory=False, usecols= ["tconst","titleType", "primaryTitle", "startYear","genres","runtimeMinutes"])
df_title_basics = data_title_basics
df_title_basics.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 10371207 entries, 0 to 10371206 Data columns (total 6 columns): # Column Dtype --- ------ ----- 0 tconst object 1 titleType object 2 primaryTitle object 3 startYear object 4 runtimeMinutes object 5 genres object dtypes: object(6) memory usage: 474.8+ MB
# DataFrame des titres de films (originaux) filtrée sur MOVIES
df_title_basics_movies = df_title_basics.loc[(df_title_basics.titleType.str.contains("movie"))]
df_title_basics_movies.head()
| tconst | titleType | primaryTitle | startYear | runtimeMinutes | genres | |
|---|---|---|---|---|---|---|
| 8 | tt0000009 | movie | Miss Jerry | 1894 | 45 | Romance |
| 144 | tt0000147 | movie | The Corbett-Fitzsimmons Fight | 1897 | 100 | Documentary,News,Sport |
| 498 | tt0000502 | movie | Bohemios | 1905 | 100 | \N |
| 570 | tt0000574 | movie | The Story of the Kelly Gang | 1906 | 70 | Action,Adventure,Biography |
| 587 | tt0000591 | movie | The Prodigal Son | 1907 | 90 | Drama |
df_title_basics_movies.info()
<class 'pandas.core.frame.DataFrame'> Index: 664838 entries, 8 to 10371157 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 tconst 664838 non-null object 1 titleType 664838 non-null object 2 primaryTitle 664836 non-null object 3 startYear 664838 non-null object 4 runtimeMinutes 664838 non-null object 5 genres 664838 non-null object dtypes: object(6) memory usage: 35.5+ MB
# Fusion des dataframes contenant tous les noms acteurs, producteurs, etc
df_name_basics = pd.read_csv(link_name_basics, compression='gzip', header=0, sep='\t')
df_title_crew = pd.read_csv(link_title_crew, compression='gzip', header=0, sep='\t')
df_prod = pd.merge(df_title_crew,df_name_basics, left_on="directors", right_on="nconst", how="left")
df_prod.head()
| tconst | directors | writers | nconst | primaryName | birthYear | deathYear | primaryProfession | knownForTitles | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | tt0000001 | nm0005690 | \N | nm0005690 | William K.L. Dickson | 1860 | 1935 | cinematographer,director,producer | tt1496763,tt0219560,tt0308254,tt1428455 |
| 1 | tt0000002 | nm0721526 | \N | nm0721526 | Émile Reynaud | 1844 | 1918 | director,animation_department,producer | tt0000003,tt16763740,tt16763674,tt27119262 |
| 2 | tt0000003 | nm0721526 | \N | nm0721526 | Émile Reynaud | 1844 | 1918 | director,animation_department,producer | tt0000003,tt16763740,tt16763674,tt27119262 |
| 3 | tt0000004 | nm0721526 | \N | nm0721526 | Émile Reynaud | 1844 | 1918 | director,animation_department,producer | tt0000003,tt16763740,tt16763674,tt27119262 |
| 4 | tt0000005 | nm0005690 | \N | nm0005690 | William K.L. Dickson | 1860 | 1935 | cinematographer,director,producer | tt1496763,tt0219560,tt0308254,tt1428455 |
# Rajout des noms de producteurs à la dataframe de référence
df_prod_2 = df_prod[["tconst","primaryName","primaryProfession"]]
df_base_dir = pd.merge(df_title_basics_movies, df_prod_2, how="left", on="tconst")
# Rajout des ratings à la dataframe de référence
df_title_ratings = pd.read_csv(link_title_ratings, compression='gzip', header=0, sep='\t')
df_movies_ratings = pd.merge(df_base_dir, df_title_ratings, how="left", on="tconst")
# Fusion entre la dataframe des acteurs avec celle des noms de personnalités du cinéma
df_acteur = pd.read_csv(link_title_principals, compression='gzip', header=0, sep='\t', low_memory=False)
df_acteur= df_acteur.loc[(df_acteur["category"]=="actor")|(df_acteur["category"]=="actress")]
df_actor = pd.merge(df_acteur,df_name_basics, left_on="nconst", right_on="nconst", how="left")
# Rajout de la dataframe des acteurs à la dataframe de référence
grouped_actors = df_actor.groupby('tconst')['primaryName'].apply(list).reset_index(name='Acteurs')
df_movies_actors = pd.merge(df_movies_ratings, grouped_actors, how="left", left_on="tconst", right_on="tconst")
# Fusion entre les dataframe IMDB et TMDB
df_ALL = pd.merge(df_movies_actors, df_tmdb, how="left", left_on="tconst", right_on="imdb_id")
df_ALL.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 664838 entries, 0 to 664837 Data columns (total 16 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 tconst 664838 non-null object 1 titleType 664838 non-null object 2 primaryTitle 664836 non-null object 3 startYear 664838 non-null object 4 runtimeMinutes 664838 non-null object 5 genres_x 664838 non-null object 6 primaryName 542581 non-null object 7 primaryProfession 542415 non-null object 8 averageRating 300881 non-null float64 9 numVotes 300881 non-null float64 10 Acteurs 482500 non-null object 11 genres_y 205814 non-null object 12 id 205814 non-null float64 13 imdb_id 205814 non-null object 14 poster_path 185120 non-null object 15 revenue 205814 non-null float64 dtypes: float64(4), object(12) memory usage: 81.2+ MB
# Localisation de tous les \N
df_ALL.loc[(df_ALL["startYear"] =='\\N') |(df_ALL["genres_x"] =='\\N') |(df_ALL["runtimeMinutes"] =='\\N')]
| tconst | titleType | primaryTitle | startYear | runtimeMinutes | genres_x | primaryName | primaryProfession | averageRating | numVotes | Acteurs | genres_y | id | imdb_id | poster_path | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | tt0000502 | movie | Bohemios | 1905 | 100 | \N | Ricardo de Baños | director,cinematographer,writer | 4.1 | 15.0 | [Antonio del Pozo, El Mochuelo] | NaN | NaN | NaN | NaN | NaN |
| 5 | tt0000615 | movie | Robbery Under Arms | 1907 | \N | Drama | Charles MacMahon | director,writer,producer | 4.3 | 25.0 | [Jim Gerald, George Merriman, Lance Vane, Will... | NaN | NaN | NaN | NaN | NaN |
| 6 | tt0000630 | movie | Hamlet | 1908 | \N | Drama | Mario Caserini | director,actor,writer | 2.9 | 27.0 | [Fernanda Negri Pouget] | NaN | NaN | NaN | NaN | NaN |
| 7 | tt0000675 | movie | Don Quijote | 1908 | \N | Drama | Narciso Cuyàs | director,cinematographer,writer | 4.2 | 20.0 | NaN | NaN | NaN | NaN | NaN | NaN |
| 9 | tt0000838 | movie | A Cultura do Cacau | 1909 | \N | \N | Ernesto de Albuquerque | director,cinematographer,editor | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 664824 | tt9916178 | movie | Yesterday's Dreams | \N | \N | \N | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 664826 | tt9916188 | movie | Minotaur | \N | \N | Thriller | Dean Israelite | director,producer,writer | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 664830 | tt9916428 | movie | The Secret of China | 2019 | \N | Adventure,History,War | Jixing Wang | director,writer | 3.5 | 17.0 | [Kenan Heppe, Wang Peng Kai, Valery Gadreau, W... | NaN | NaN | NaN | NaN | NaN |
| 664832 | tt9916620 | movie | The Copeland Case | \N | \N | Drama | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 664835 | tt9916706 | movie | Dankyavar Danka | 2013 | \N | Comedy | Kanchan Nayak | director,assistant_director | NaN | NaN | [Suvarna Kale, Makarand Anaspure, Anvay Bendre... | NaN | NaN | NaN | NaN | NaN |
278146 rows × 16 columns
# Fonctions pour supprimer les \N
def remove_N_year(row):
return row['startYear'] != '\\N'
def remove_N_genres(row):
return row['genres_x'] != '\\N'
def remove_N_runtime(row):
return row['runtimeMinutes'] != '\\N'
# Fonction principale de nettoyage
def remove_rows(df_ALL):
df_ALL = df_ALL[df_ALL.apply(remove_N_year, axis=1) &
df_ALL.apply(remove_N_genres, axis=1) &
df_ALL.apply(remove_N_runtime, axis=1)]
return df_ALL
# Application de la fonction sur notre dataframe
df_ALL = remove_rows(df_ALL)
df_ALL["revenue"].isna().value_counts()
revenue True 199993 False 186699 Name: count, dtype: int64
# Nous supprimons toutes les valeurs manquantes et à 0 pour la colonne Revenue.
df_ALL = df_ALL.drop(df_ALL[df_ALL["revenue"] == 0].index)
df_ALL.dropna(subset=["revenue"], inplace=True)
df_ALL["revenue"].isna().value_counts()
revenue False 14491 Name: count, dtype: int64
df_ALL['runtimeMinutes'].info()
<class 'pandas.core.series.Series'> Index: 14491 entries, 348 to 664800 Series name: runtimeMinutes Non-Null Count Dtype -------------- ----- 14491 non-null object dtypes: object(1) memory usage: 226.4+ KB
# Modification du Type de la colonne RuntimeMinutes en Int
df_ALL['runtimeMinutes'] = df_ALL['runtimeMinutes'].astype(str).astype(int)
# Visualisation de la distribution de la durée des films
fig = px.violin(df_ALL, y="runtimeMinutes")
fig.update_layout(title_text='Distribution des Durées de Films')
fig.show()
Nous allons décider de filtrer sur la durée entre 60 min et 180 minutes pour éviter les valeurs abbérantes.
# On filtre sur les durées de films entre 1h et 3h
df_ALL = df_ALL[(df_ALL['runtimeMinutes'] >= 60) & (df_ALL['runtimeMinutes'] <= 180)]
df_ALL['startYear'].info()
<class 'pandas.core.series.Series'> Index: 14339 entries, 348 to 664800 Series name: startYear Non-Null Count Dtype -------------- ----- 14339 non-null object dtypes: object(1) memory usage: 224.0+ KB
# Transformation de la colonne startYear en Année
df_ALL['startYear'] = pd.to_datetime(df_ALL['startYear'], format='%Y')
df_ALL['startYear'] = df_ALL['startYear'].dt.year
# Visualisation de la distribution de la durée des films
df_ALL['Decade'] = (df_ALL['startYear'] // 10) * 10
# Tracer la distribution par décennie
fig = px.box(df_ALL, y="Decade")
fig.update_layout(title_text='Distribution des années de sortie des films par décennie')
fig.show()
On décide de prendre les films entre les années 1990 jusque 2020 pour avoir un large choix de film après nos filtres.
# Filtre sur les films sortis entre 1990 et 2020
df_ALL["startYear"] = (pd.to_datetime(df_ALL['startYear'], format='%Y')).apply(lambda x: x.year)
df_movies_cleaned = df_ALL.loc[(df_ALL["startYear"] >= 1990) & (df_ALL["startYear"] <= 2020)]
# Visualisation du nombre de film par genre
df_movies_explo = df_movies_cleaned['genres_x'].str.split(',')
df_movies_explo
all_genres = [genre for genres in df_movies_explo if genres is not pd.NA for genre in genres]
all_genres
genre_counts = pd.Series(all_genres).value_counts()
# Graphique à barres pour les genres
genre_counts.plot(kind='bar')
plt.title('Nombre de films par genre')
plt.xlabel('Genre')
plt.ylabel('Nombre de films')
plt.show()
Nous voyons gràce à ce graphique que le genre "Comedy" est trés bien représenté dans cette base de données. Pour les genres "Crime" et "Thriller", la proportion est plus ou moins équivalente.
# Renommage des colonnes/suppression des colonnes inutiles
df_movies_cleaned.rename(columns={"primaryTitle":"Titre", "startYear":"Annee_de_sortie", "runtimeMinutes":"Duree", "genres_x":"Genre", "primaryName":"Realisateur", "averageRating":"Note", "numVotes":"Nombre_de_votants", "poster_path":"Affiche", "revenue":"Recette","Acteurs":"Acteur" }, inplace=True)
df_movies_cleaned.drop(columns=["titleType", "genres_y", "tconst","primaryProfession","id","imdb_id", "Decade"],inplace=True)
df_movies_cleaned.head()
| Titre | Annee_de_sortie | Duree | Genre | Realisateur | Note | Nombre_de_votants | Acteur | Affiche | Recette | |
|---|---|---|---|---|---|---|---|---|---|---|
| 24400 | Kate & Leopold | 2001 | 118 | Comedy,Fantasy,Romance | James Mangold | 6.4 | 88083.0 | [Meg Ryan, Hugh Jackman, Liev Schreiber, Breck... | /mUvikzKJJSg9khrVdxK8kg3TMHA.jpg | 76019048.0 |
| 68635 | Aquí huele a muerto... (¡pues yo no he sido!) | 1990 | 88 | Comedy,Horror | Álvaro Sáenz de Heredia | 3.9 | 392.0 | [Josema Yuste, Millán Salcedo, Ana Álvarez, Ra... | /fuB7IKCoJr0w3LG4BRiET5YoLbZ.jpg | 3073994.0 |
| 68668 | Countdown to Esmeralda Bay | 1990 | 90 | Action,Drama,War | Jesús Franco | 3.6 | 153.0 | [Robert Forster, George Kennedy, Fernando Rey,... | /gjnb09vzG4WV8BCer3viifKyO5g.jpg | 94104.0 |
| 69295 | The Master | 1992 | 92 | Action,Comedy,Crime | Hark Tsui | 5.7 | 2956.0 | [Jet Li, Wah Yuen, Crystal Kwok, Jerry Trimble] | /i4v3uQVayPXTGwDjRf8n1iyd2TR.jpg | 8096542.0 |
| 69484 | Pareja enloquecida busca madre de alquiler | 1990 | 97 | Comedy | Mariano Ozores | 4.3 | 34.0 | [José Luis López Vázquez, Lola Forner, Guiller... | /wqEnYz4ZG43xMm6DXXoJcnL51de.jpg | 195914.0 |
# On souhaite n'avoir que les films des genres Thriller, Crime et Comedy
df_movies_genre = df_movies_cleaned.loc[(df_movies_cleaned.Genre.str.contains("|".join(["Thriller","Crime","Comedy"])))]
sample_size = 700000
random_df_title_ratings = df_title_ratings.sample(n=sample_size, random_state=50)
plt.figure(figsize=(15, 8))
sns.lineplot(x = 'averageRating', y = 'numVotes', data = random_df_title_ratings)
plt.title("Nombre de votants par notes moyennes")
plt.xlabel("Notes moyennes")
plt.ylabel("Nombre de votants")
plt.show()
Pour cette analyse, nous procédons à un échantillonnage car il n'est pas praticable de générer des visualisations directes sur notre data frame actuel. Ce dernier contient contient un nombre important de lignes à cette étape. L'objectif de cette visualisation est d'évaluer si les films ayant reçu les meilleures notes bénéficient d'un nombre de votants suffisant pour garantir l'intégrité de la note finale. Nous observons qu'à mesure que les films obtiennent des notes plus élevées, le nombre de votants augmente (on peut les qualifier de films 'populaires'). Ainsi, il semble judicieux de restreindre notre sélection aux films ayant obtenu des notes de 7 et plus, étant donné que ceux-ci sont plus susceptibles d'avoir un nombre de votants significatif. Cette approche réduit le risque de biais dans notre analyse en se concentrant sur des films bien notés et également populaires.
fig = px.violin(df_movies_genre, y="Note")
fig.update_layout(title_text='Distribution des Notes de Films')
fig.show()
Ce graphique nous confirme notre décision de prendre tous les films dont la note est supérieur 7.
# On souhaite n'afficher que les films qui ont une note supérieur à 7
df_rated = df_movies_genre.loc[(df_movies_genre["Note"]) >= 7.0]
# On décide de n'afficher que les films dont les votes ont atteint plus de 300 dans un souci de pertinence
df_final = df_rated.loc[(df_movies_genre["Nombre_de_votants"]) >= 300]
df_final.sort_values("Nombre_de_votants", ascending=False).head()
| Titre | Annee_de_sortie | Duree | Genre | Realisateur | Note | Nombre_de_votants | Acteur | Affiche | Recette | |
|---|---|---|---|---|---|---|---|---|---|---|
| 208227 | The Dark Knight | 2008 | 152 | Action,Crime,Drama | Christopher Nolan | 9.0 | 2806908.0 | [Christian Bale, Heath Ledger, Aaron Eckhart, ... | /qJ2tW6WMUDux911r6m7haRef0WH.jpg | 1.004558e+09 |
| 77262 | Pulp Fiction | 1994 | 154 | Crime,Drama | Quentin Tarantino | 8.9 | 2166539.0 | [John Travolta, Uma Thurman, Samuel L. Jackson... | /d5iIlFn5s0ImszYzBPb8JPIfbXD.jpg | 2.141791e+08 |
| 302165 | The Dark Knight Rises | 2012 | 164 | Action,Drama,Thriller | Christopher Nolan | 8.4 | 1790465.0 | [Christian Bale, Tom Hardy, Anne Hathaway, Gar... | /85cWkCVftiVs0BVey6pxX8uNmLt.jpg | 1.081041e+09 |
| 79103 | Se7en | 1995 | 127 | Crime,Drama,Mystery | David Fincher | 8.6 | 1753458.0 | [Morgan Freeman, Brad Pitt, Kevin Spacey, Andr... | /6yoghtyTpznpBik8EngEmJskVUO.jpg | 3.273119e+08 |
| 185908 | Batman Begins | 2005 | 140 | Action,Crime,Drama | Christopher Nolan | 8.2 | 1546845.0 | [Christian Bale, Michael Caine, Ken Watanabe, ... | /4MpN4kIEqUjW8OPtOQJXlTdHiJV.jpg | 3.742187e+08 |
# Visualisation des colonnes ayant des valeurs nulles
df_final.isna().sum()
Titre 0 Annee_de_sortie 0 Duree 0 Genre 0 Realisateur 118 Note 0 Nombre_de_votants 0 Acteur 38 Affiche 0 Recette 0 dtype: int64
# On remplace les valeurs nulles
df_final["Affiche"].fillna("/nX5XotM9yprCKarRH4fzOq1VM1J.jpg", inplace=True)
df_final["Realisateur"].fillna("Non renseigné", inplace=True)
df_final["Acteur"].fillna("Non renseigné", inplace=True)
df_final.info()
<class 'pandas.core.frame.DataFrame'> Index: 1378 entries, 70037 to 663091 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Titre 1378 non-null object 1 Annee_de_sortie 1378 non-null int64 2 Duree 1378 non-null int32 3 Genre 1378 non-null object 4 Realisateur 1378 non-null object 5 Note 1378 non-null float64 6 Nombre_de_votants 1378 non-null float64 7 Acteur 1378 non-null object 8 Affiche 1378 non-null object 9 Recette 1378 non-null float64 dtypes: float64(3), int32(1), int64(1), object(5) memory usage: 113.0+ KB
# Visualisation en pairplot des colonnes numériques
DF_FINAL_pop_sample = df_final.sample(frac=0.25)
# Création du pairplot
pairplot = sns.pairplot(DF_FINAL_pop_sample)
pairplot.fig.suptitle("Relations entre les Variables dans un Échantillon de Films (25%)", y=1.02)
plt.show()
C:\ProgramData\anaconda3\Lib\site-packages\seaborn\axisgrid.py:118: UserWarning: The figure layout has changed to tight
On peut voir que la répartition des films sur les années et la durée est plutôt bien équilibrée. La majorité des films ont une note entre 7 et 8. Le nombre de votants et les recettes sont très regroupés dans les premières valeurs et sont éparpillés.
# On crée une copie de notre dataframe de référence afin de pouvoir travailler sur la colonne Genre et éclater ces derniers
df_stat = df_final
df_stat['Genre'] = df_stat['Genre'].str.split(',')
# Explode de la colonne "Genre"
df_genre_expanded = df_stat.explode('Genre')
# Réinitialisation des index pour avoir un index continu
df_genre_expanded.reset_index(drop=True, inplace=True)
# Filtre sur les genres Thriller, Crime et Comedy
df_genre_expanded = df_genre_expanded.loc[(df_genre_expanded.Genre.str.contains("|".join(["Thriller","Crime","Comedy"])))]
# Suppression des doublons sur les colonnes Titre et Année de sortie
df_Film_Pulse_AI = df_genre_expanded.drop_duplicates(subset=["Titre", "Annee_de_sortie"])
df_Film_Pulse_AI.info()
<class 'pandas.core.frame.DataFrame'> Index: 1378 entries, 1 to 3687 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Titre 1378 non-null object 1 Annee_de_sortie 1378 non-null int64 2 Duree 1378 non-null int32 3 Genre 1378 non-null object 4 Realisateur 1378 non-null object 5 Note 1378 non-null float64 6 Nombre_de_votants 1378 non-null float64 7 Acteur 1378 non-null object 8 Affiche 1378 non-null object 9 Recette 1378 non-null float64 dtypes: float64(3), int32(1), int64(1), object(5) memory usage: 113.0+ KB
Nous pouvons voir que nous n'avons plus aucune valeur manquante dans notre dataset.
# Affichage des films par Nombre de votants
df_Film_Pulse_AI.sort_values("Nombre_de_votants", ascending=False).head()
| Titre | Annee_de_sortie | Duree | Genre | Realisateur | Note | Nombre_de_votants | Acteur | Affiche | Recette | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1607 | The Dark Knight | 2008 | 152 | Crime | Christopher Nolan | 9.0 | 2806908.0 | [Christian Bale, Heath Ledger, Aaron Eckhart, ... | /qJ2tW6WMUDux911r6m7haRef0WH.jpg | 1.004558e+09 |
| 306 | Pulp Fiction | 1994 | 154 | Crime | Quentin Tarantino | 8.9 | 2166539.0 | [John Travolta, Uma Thurman, Samuel L. Jackson... | /d5iIlFn5s0ImszYzBPb8JPIfbXD.jpg | 2.141791e+08 |
| 2205 | The Dark Knight Rises | 2012 | 164 | Thriller | Christopher Nolan | 8.4 | 1790465.0 | [Christian Bale, Tom Hardy, Anne Hathaway, Gar... | /85cWkCVftiVs0BVey6pxX8uNmLt.jpg | 1.081041e+09 |
| 374 | Se7en | 1995 | 127 | Crime | David Fincher | 8.6 | 1753458.0 | [Morgan Freeman, Brad Pitt, Kevin Spacey, Andr... | /6yoghtyTpznpBik8EngEmJskVUO.jpg | 3.273119e+08 |
| 1227 | Batman Begins | 2005 | 140 | Crime | Christopher Nolan | 8.2 | 1546845.0 | [Christian Bale, Michael Caine, Ken Watanabe, ... | /4MpN4kIEqUjW8OPtOQJXlTdHiJV.jpg | 3.742187e+08 |
# Utilisation de cette DataFrame pour l'établissement des KPIs à destination du client
df_final_TOP10_acteurs = df_Film_Pulse_AI.explode('Acteur')
df_final_TOP10_acteurs
| Titre | Annee_de_sortie | Duree | Genre | Realisateur | Note | Nombre_de_votants | Acteur | Affiche | Recette | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Back to the Future Part III | 1990 | 118 | Comedy | Robert Zemeckis | 7.4 | 471915.0 | Michael J. Fox | /crzoVQnMzIrRfHtQw0tLBirNfVg.jpg | 244527583.0 |
| 1 | Back to the Future Part III | 1990 | 118 | Comedy | Robert Zemeckis | 7.4 | 471915.0 | Christopher Lloyd | /crzoVQnMzIrRfHtQw0tLBirNfVg.jpg | 244527583.0 |
| 1 | Back to the Future Part III | 1990 | 118 | Comedy | Robert Zemeckis | 7.4 | 471915.0 | Mary Steenburgen | /crzoVQnMzIrRfHtQw0tLBirNfVg.jpg | 244527583.0 |
| 1 | Back to the Future Part III | 1990 | 118 | Comedy | Robert Zemeckis | 7.4 | 471915.0 | Tom Wilson | /crzoVQnMzIrRfHtQw0tLBirNfVg.jpg | 244527583.0 |
| 3 | Cyrano de Bergerac | 1990 | 137 | Comedy | Jean-Paul Rappeneau | 7.5 | 25543.0 | Gérard Depardieu | /80XJ5UkGuYTKDuALeG03BLk1OT1.jpg | 5822041.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3683 | Beasts Clawing at Straws | 2020 | 108 | Crime | Kim Yong-hoon | 7.0 | 5399.0 | Youn Yuh-jung | /lO4hjVBxrVtMmupGraIR3c7Jq1Q.jpg | 5707415.0 |
| 3687 | Law of Tehran | 2019 | 131 | Crime | Saeed Roustayi | 7.8 | 17805.0 | Payman Maadi | /ujNhy2Vu7S1FHuwePMIYMkIbGTj.jpg | 1350772.0 |
| 3687 | Law of Tehran | 2019 | 131 | Crime | Saeed Roustayi | 7.8 | 17805.0 | Navid Mohammadzadeh | /ujNhy2Vu7S1FHuwePMIYMkIbGTj.jpg | 1350772.0 |
| 3687 | Law of Tehran | 2019 | 131 | Crime | Saeed Roustayi | 7.8 | 17805.0 | Parinaz Izadyar | /ujNhy2Vu7S1FHuwePMIYMkIbGTj.jpg | 1350772.0 |
| 3687 | Law of Tehran | 2019 | 131 | Crime | Saeed Roustayi | 7.8 | 17805.0 | Farhad Aslani | /ujNhy2Vu7S1FHuwePMIYMkIbGTj.jpg | 1350772.0 |
5435 rows × 10 columns
df_Film_Pulse_AI.info()
<class 'pandas.core.frame.DataFrame'> Index: 1378 entries, 1 to 3687 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Titre 1378 non-null object 1 Annee_de_sortie 1378 non-null int64 2 Duree 1378 non-null int32 3 Genre 1378 non-null object 4 Realisateur 1378 non-null object 5 Note 1378 non-null float64 6 Nombre_de_votants 1378 non-null float64 7 Acteur 1378 non-null object 8 Affiche 1378 non-null object 9 Recette 1378 non-null float64 dtypes: float64(3), int32(1), int64(1), object(5) memory usage: 113.0+ KB
# Sauvegarde du Dataframe en fichier CSV
df_Film_Pulse_AI.to_csv('df_Film_Pulse_AI.csv', index=True)
# Sauvegarde du Dataframe en fichier CSV
df_final_TOP10_acteurs.to_csv('df_final_TOP10_acteurs.csv', index=True)